﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace Odyssey.Http.Implementations
{
    internal partial class HttpRequester
    {
        public virtual async Task<T> PostAsync<T>(string uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null) 
        {
            return await PostAsync<T>(new Uri(uri), data, clientName, contentType, requestHeaders, httpSerializer, responseMessagefilter);
        }

        public virtual async Task<T> PostAsync<T>(Uri uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null) 
        {
            httpSerializer = httpSerializer ?? _httpSerializer;
            var responseMessage = await PostAsync(uri, data, clientName, contentType, requestHeaders, responseMessagefilter);
            var jsonContent = await responseMessage.Content.ReadAsStringAsync();
            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"post uri=[{uri.ToString()}] responsedata[{jsonContent}]");
            }
            return httpSerializer.Deserialize<T>(jsonContent);
        }

        public virtual async Task<TResponse> PostAsync<TRequest, TResponse>(string uri, TRequest data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null) 
        {
            return await PostAsync<TRequest, TResponse>(new Uri(uri), data, clientName, contentType, requestHeaders, httpSerializer, responseMessagefilter);
        }

        public virtual async Task<TResponse> PostAsync<TRequest, TResponse>(Uri uri, TRequest data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null) 
        {
            httpSerializer = httpSerializer ?? _httpSerializer;
            var jsonData = httpSerializer.Serialize(data);
            var responseMessage = await PostAsync(uri, jsonData, clientName, contentType, requestHeaders, responseMessagefilter);
            var jsonContent = await responseMessage.Content.ReadAsStringAsync();
            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"post uri=[{uri.ToString()}] responsedata[{jsonContent}]");
            }
            return httpSerializer.Deserialize<TResponse>(jsonContent);
        }

        public virtual async Task<HttpResponseMessage> PostAsync(string uri, object data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            return await PostAsync(new Uri(uri), data, clientName, contentType, requestHeaders, httpSerializer, responseMessagefilter);
        }

        public virtual async Task<HttpResponseMessage> PostAsync(Uri uri, object data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            httpSerializer = httpSerializer ?? _httpSerializer;
            var jsonData = httpSerializer.Serialize(data);
            return await PostAsync(uri, jsonData, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<HttpResponseMessage> PostAsync(string uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            return await PostAsync(new Uri(uri), data, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<HttpResponseMessage> PostAsync(Uri uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            return await SendAsync(uri, data, HttpMethod.Post, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<string> PostStringAsync(string uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            return await PostStringAsync(new Uri(uri), data, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<string> PostStringAsync(Uri uri, string data, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            var responseMessage = await PostAsync(uri, data, clientName, contentType, requestHeaders, responseMessagefilter);
            var jsonContent = await responseMessage.Content.ReadAsStringAsync();
            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"post uri=[{uri.ToString()}] responsedata[{jsonContent}]");
            }
            return jsonContent;
        }
    }
}
